home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / ctc 1.6 / ctc.c next >
Encoding:
C/C++ Source or Header  |  1994-01-17  |  14.6 KB  |  557 lines  |  [TEXT/KAHL]

  1. /**********
  2. >>   change the file type and creator of any file dropped onto this program.
  3. >>     Prompts for the file type and creator, and changes all files dropped at
  4. >>   the same time to the same type and creator.
  5.  
  6.     This program is a modified version of:
  7.  
  8. >>    ctc v1.4    
  9. >>    Written by Brian Bechtel, based on code by Juri Munkki
  10. >>    Feel free to use the code in your programs.
  11.     
  12.     History...
  13.     V1.5        Added:    EOL - CR, LF, CR/LF translation of text files.
  14.     V1.6    RMF    Added:    Balloon help resource for finder
  15.                         Options to change type, creator or both
  16.                         Now displays file name, old type, and creator
  17.                         Made dialog window movable
  18. */
  19. #include <Gestalt.h>
  20. #include <pascal.h>
  21. #include <Menus.h>
  22. #include <Files.h>
  23. #include <Folders.h>
  24. #include <Fonts.h>
  25. #include <Dialogs.h>
  26. #include <Memory.h>
  27. #include <SegLoad.h>
  28. #include <BDC.h>
  29. #include <OSUtils.h>
  30. #include "ctc.h"
  31.  
  32. /* Tells the Dialog Manager that there is an edit line in this dialog, and */ 
  33. /* it should track and change to an I-Beam cursor when over the edit line */
  34. pascal OSErr SetDialogTracksCursor(DialogPtr theDialog, Boolean tracks)
  35.     = { 0x303C, 0x0306, 0xAA68 };
  36.  
  37. pascal OSErr GetStdFilterProc(ProcPtr *theProc)
  38.         = {0x303C, 0x0203, 0xAA68};
  39.  
  40. pascal OSErr SetDialogDefaultItem (DialogPtr theDialog,
  41.         short newItem) = {0x303C,0x0304,0xAA68};
  42.  
  43.  
  44. pascal OSErr SetDialogCancelItem (DialogPtr theDialog,
  45.         short newItem) = {0x303C,0x0305,0xAA68};
  46.  
  47.  
  48. void ConvertFile (char *thefile, short EOLmode);
  49.  
  50. pascal Boolean GenericFilter();
  51.         
  52. /* from tickle.c */
  53. OSErr TickleParent( FSSpec *);
  54. OSErr MakeWDSpec( FSSpec *, short, ConstStr255Param );
  55. /*****************
  56.     Support for EOL code....
  57.     
  58.     Modified by RMF to remove unneeded: FindControl call. 
  59. */
  60. void PopRadioButton (DialogPtr dPtr, short button)
  61. {    Handle            itemHandle;
  62.     short            itemType;
  63.     Rect            box;
  64.     
  65.     GetDItem(dPtr, button, &itemType, &itemHandle, &box);
  66.     SetCtlValue(itemHandle, false);
  67. }
  68.  
  69. void PushRadioButton (DialogPtr dPtr, short button)
  70. {    Handle            itemHandle;
  71.     short            itemType;
  72.     Rect            box;
  73.     
  74.     PopRadioButton (dPtr, DOS);
  75.     PopRadioButton (dPtr, IGNORE);
  76.     PopRadioButton (dPtr, MAC);
  77.     PopRadioButton (dPtr, UNIX);
  78.     GetDItem(dPtr, button, &itemType, &itemHandle, &box);
  79.     SetCtlValue(itemHandle, true);
  80. }
  81.  
  82. /*************************************************************
  83.     Display error number if error occures
  84. */
  85. void ReportError(OSErr err)
  86. {    Str15 errStr;
  87.  
  88.     NumToString((long) err, errStr);
  89.     ParamText(errStr, "\p", nil, nil);
  90.     StopAlert(129, nil);
  91.     ParamText("\p", nil, nil, nil);
  92.     
  93. }
  94. /**********************************************************************
  95.     Set a Edit Text area to file type or creator
  96. */
  97. void SetDialogItemType(long typeCreator, short itemHit, DialogPtr dPtr)
  98. {    Handle        itemHandle;
  99.     short        itemType;
  100.     Rect        box;
  101.     Str255        itemString;
  102.  
  103.     itemString[0] = 4;    /* establish artificial length */
  104.     GetDItem(dPtr, itemHit, &itemType, &itemHandle, &box);
  105.     BlockMove(&typeCreator, (Ptr)&itemString[1], 4);
  106.     SetIText(itemHandle, itemString);
  107.     
  108. }     /* End of () */
  109.  
  110. /**********************************************************************
  111.     Get from a Edit Text area a file type or creator
  112.     
  113.     Returns: True if got valid file Type
  114. */
  115. Boolean GetDialogItemType(long *typeCreator, short itemHit, DialogPtr dPtr)
  116. {    Handle        itemHandle;
  117.     short        itemType;
  118.     Rect        box;
  119.     Str255        itemString;
  120.  
  121.     GetDItem(dPtr, itemHit, &itemType, &itemHandle, &box);
  122.     GetIText(itemHandle, itemString);
  123.     *typeCreator = 0L;
  124.     if (itemString[0] >= 4) 
  125.         BlockMove((Ptr)&itemString[1], typeCreator, 4);
  126.     else ;                    /* File type not specified */
  127.     
  128.     return (itemString[0] >= 4);
  129. }     /* End of () */
  130.  
  131. /**********************************************************************
  132.     Get get the file file information of interest (eg. type or creator)
  133.     
  134.     Returns: OSErr
  135. */
  136. OSErr SetUpFileParam(AppFile *thefile, CInfoPBRec *block)
  137. {    OSErr        err;
  138.     
  139.     block->hFileInfo.ioCompletion=0;
  140.     block->hFileInfo.ioNamePtr=thefile->fName;
  141.     block->hFileInfo.ioVRefNum=thefile->vRefNum;
  142.     block->hFileInfo.ioFVersNum=0;
  143.     block->hFileInfo.ioFDirIndex=0;
  144.  
  145.     err = PBGetFInfoSync( block );
  146.     
  147.     return err;
  148. }    /* End of () */
  149.  
  150.  
  151. /**********************************************************************
  152.     Get get the file file information of interest (eg. type or creator)
  153.     
  154.     Returns: OSErr
  155. */
  156. OSErr FSSetUpFileParam(FSSpec *thefile, CInfoPBRec *block)
  157. {    OSErr        err;
  158.     
  159.     block->hFileInfo.ioCompletion=0;
  160.     block->hFileInfo.ioNamePtr=thefile->name;
  161.     block->hFileInfo.ioVRefNum=thefile->vRefNum;
  162.     block->hFileInfo.ioFVersNum=0;
  163.     block->hFileInfo.ioFDirIndex=-1;
  164.     block->hFileInfo.ioDirID= thefile->parID;
  165.     block->hFileInfo.ioFlParID= thefile->parID;
  166.     
  167.     err = PBGetFInfoSync( block );
  168.     
  169.     return err;
  170. }    /* End of () */
  171.  
  172. OSErr ReadHeader(FSSpec *sfFilePtr, long *data)
  173. {    OSErr err;
  174.     long longCount;
  175.     short fRef;
  176.     
  177.     *data = 0L;
  178.     
  179.     err = FSpOpenDF(sfFilePtr, fsRdPerm, &fRef);
  180.     if (err == noErr) {                 
  181.         err = SetFPos(fRef, fsFromStart, 0L);    /* skip header*/
  182.         if (err == noErr) {
  183.               longCount = sizeof(long);
  184.             err = FSRead(fRef, &longCount, (Ptr)data);
  185.             }
  186.         }
  187.     FSClose(fRef);                                /* close the input file */
  188.     if (err == eofErr) err = noErr;                /* May not have an Data fork! */
  189.     return err;
  190. }    /* End of () */
  191.  
  192. long    LookType(FSSpec *spec, long fdtype)
  193. {    OSErr    err;
  194.     long    data;
  195.     
  196.     /* Check internal file format to suggest the correct headers */
  197.     err = ReadHeader(spec, &data);
  198.     if (err == noErr) {
  199.         short    low, high;
  200.         /* TIFF = II or MM */
  201.         /* BMP  = BM */
  202.         /* EPSF  = %! */
  203.         /* GIFF = GIF87a */
  204.         low = data & 0xffff;
  205.         high = data >> 16;
  206.         if (data == 'GIF8') fdtype = 'giff';
  207.         else
  208.         if (high == 'II' || high == 'MM') fdtype = 'TIFF';
  209.         else
  210.         if (high == '%!' || high == 0xC5D0) fdtype = 'EPSF';
  211.         else
  212.         if (high == 'BM') fdtype = 'BINA';    
  213.         
  214.         
  215.     } else 
  216.         ReportError(err);
  217.     return fdtype;
  218. }    /* End of () */
  219.  
  220. Boolean    AskNewTypeCreator(DialogPtr dPtr, short sysfRef,
  221.                     long *type, long *creator, 
  222.                     short *changeType, short *changeCreator, short *EOLmode, 
  223.                     FSSpec *file)
  224. {    short        itemHit = -1;
  225.     Handle        itemHandle;
  226.     short        itemType;
  227.     Rect        itemBox;
  228.     short        temp;
  229.     Str15        sType, sCreator;
  230.     OSType        oldCreator;
  231.     OSErr err;
  232.     
  233.     OSErr GetApplicationName(OSType fCreator, FSSpec *file, short ioVRefNum);
  234.  
  235.         /* EOL support items setup */
  236.     PushRadioButton (dPtr, *EOLmode);
  237.         
  238.         /* Extra information options items setup */
  239.     
  240.     sCreator[0] = sType[0] = 4;
  241.     GetDialogItemType((long *) (&sType[1]), TYPE, dPtr);
  242.     GetDialogItemType((long *) (&sCreator[1]), CREATOR, dPtr);
  243.     ParamText(sCreator, sType, file->name, nil);
  244.     
  245.     SetDialogItemType(*creator, CREATOR, dPtr);
  246.     SetDialogItemType(*type, TYPE, dPtr);
  247.     
  248.     SelIText(dPtr, CREATOR, 0, 4);
  249.     
  250.     GetDItem(dPtr, checkCreator, &itemType, &itemHandle, &itemBox);
  251.     SetCtlValue((ControlHandle) itemHandle, (*changeCreator == 1));
  252.     GetDItem(dPtr, checkType, &itemType, &itemHandle, &itemBox);
  253.     SetCtlValue((ControlHandle) itemHandle, (*changeType == 1));
  254.     
  255.     GetDialogItemType(creator, CREATOR, dPtr);
  256.     GetDItem(dPtr, CreatorApplicationID, &itemType, &itemHandle, &itemBox);
  257.     err = GetApplicationName(*creator, file, file->vRefNum);
  258.     if (err != noErr) err = GetApplicationName(*creator, file, sysfRef);
  259.     
  260.     if (err == noErr) {
  261.         SetIText(itemHandle, file->name);
  262.         oldCreator = *creator;
  263.     } else 
  264.         SetIText(itemHandle, "\p");
  265.         
  266.     do {
  267.     
  268.         ModalDialog(GenericFilter, &itemHit);
  269.         
  270.         GetDItem(dPtr, itemHit, &itemType, &itemHandle, &itemBox);
  271.         
  272.         if ((radCtrl | ctrlItem) == itemType) {    /* Invert Check Boxes */
  273.             switch (itemHit) {
  274.                 case DOS:
  275.                 case IGNORE:
  276.                 case MAC:
  277.                 case UNIX:    PushRadioButton (dPtr, *EOLmode = itemHit);
  278.                     break;
  279.                 }
  280.         } else
  281.         
  282.         if ((chkCtrl | ctrlItem) == itemType) {    /* Invert Check Boxes */
  283.             temp = GetCtlValue((ControlHandle) itemHandle);
  284.             temp = (temp + 1) & 1;
  285.             SetCtlValue((ControlHandle) itemHandle, temp);
  286.             
  287.             switch (itemHit) {
  288.                 case checkCreator:    *changeCreator = temp;    break;
  289.                 case checkType:        *changeType = temp;        break;
  290.                     }
  291.         } else {    /* End if Check box... */
  292.             if (itemHit == CREATOR) {
  293.                 GetDialogItemType(creator, CREATOR, dPtr);
  294.                 if (*creator != oldCreator) {
  295.                     if (GetDialogItemType((long *) (&sCreator[1]), CREATOR, dPtr)) {                    
  296.                         GetDItem(dPtr, CreatorApplicationID, &itemType, &itemHandle, &itemBox);
  297.                         file->name[0] = 0;
  298.                         err = GetApplicationName((OSType) *creator,file, file->vRefNum);
  299.                         if (err != noErr)
  300.                             err = GetApplicationName(*creator, file, sysfRef);
  301.                         oldCreator = *creator;
  302.                         SetIText(itemHandle, file->name);
  303.                         }
  304.                 }
  305.             }
  306.             GetDialogItemType(type, TYPE, dPtr);
  307.             if (*type == 'TEXT') {
  308.             
  309.             } else {
  310.             
  311.             }
  312.         }
  313.     } while ((itemHit != OK) && (itemHit != CANCEL));
  314.     
  315.     if (itemHit == CANCEL)    return (false);
  316.     else {
  317.     
  318.         GetDialogItemType(type, TYPE, dPtr);
  319.         GetDialogItemType(creator, CREATOR, dPtr);
  320.         
  321.         return (true);
  322.         }
  323. }    /* End of () */
  324.  
  325.  
  326. void    HandleUpdates()
  327. {
  328. /*    Used to handle window updates for windows other than modal dialogs.*/
  329. /*    We don't have any, so return without doing anything.*/
  330. }
  331.  
  332. /******************************************************************************
  333. ** I put this call in a separate procedure to emphasize the fact that I'm
  334. ** modifying a global variable, dPtr, with the side effect of putting a dialog
  335. ** on the screen.  I don't want to display the dialog if we just double-click
  336. ** on the application, so I'm calling this routine at a wierd time.
  337. */
  338. DialogPtr DisplayDialog()
  339. {    DialogPtr    dPtr;
  340.  
  341.     ParamText("\p????", "\p????", nil, nil);
  342.     dPtr = GetNewDialog(128, nil, (WindowPtr) -1);
  343.     return dPtr;
  344. }
  345.  
  346. OSErr DoConvertEOF(FSSpec *sfFile, short EOLmode)
  347. {    OSErr err;
  348.     Str255        oldName;    /** modify the EOL characters in the file */
  349.     short        oldVol, WDRef;
  350.     
  351.     err = OpenWD(sfFile->vRefNum,sfFile->parID, 0, &WDRef); 
  352.     if (err == noErr) {
  353.         err = GetVol (oldName, &oldVol);
  354.         err = SetVol (0, WDRef);
  355.         
  356.         p2cstr(sfFile->name);
  357.         ConvertFile ((char *) sfFile->name, EOLmode);
  358.         c2pstr((char *) sfFile->name);
  359.         
  360.         err = CloseWD(WDRef); 
  361.         err = SetVol (0, oldVol);
  362.         }
  363.     return err;            
  364. }    /* End of () */
  365.  
  366. void ProcessFiles(DialogPtr dPtr, short count, short sysRef)
  367. {    AppFile        thefile;
  368.     FInfo        ioFlFndrInfo;
  369.     FSSpec        spec;
  370.     OSErr         err;
  371.     
  372. /********************************************************************************
  373. >>   change the file type and creator of any file dropped onto this program.
  374. */
  375.     GetAppFiles(1,&thefile);                /* get Type & Creator of 1st file. */
  376.     err = MakeWDSpec(&spec, thefile.vRefNum, thefile.fName );
  377.     if (err == noErr) {
  378.         err = FSpGetFInfo(&spec, &ioFlFndrInfo);
  379.         }
  380.     
  381.     if (err == noErr) {
  382.     
  383.         long        type, creator;
  384.         short        EOLmode, changeType, changeCreator, i;
  385.     
  386.         changeType = changeCreator = true;
  387.         EOLmode = IGNORE;
  388.  
  389.         creator = ioFlFndrInfo.fdCreator;
  390.         SetDialogItemType(creator, CREATOR, dPtr);
  391.         type = ioFlFndrInfo.fdType;
  392.         SetDialogItemType(type, TYPE, dPtr);
  393.         type = LookType(&spec, ioFlFndrInfo.fdType);
  394.         
  395.         /* Prompts for the file type and creator, 
  396.         */
  397.         if (AskNewTypeCreator(dPtr, sysRef,
  398.                                 &type, &creator, &changeType, &changeCreator, 
  399.                                 &EOLmode, &spec)) {
  400.             
  401.             for(i=1; i<=count && err == noErr; i++)    {
  402.                 /* changes all files dropped at the same time 
  403.                 ** to the same type and creator.
  404.                 */
  405.                 GetAppFiles(i,&thefile);
  406.                 err = MakeWDSpec(&spec, thefile.vRefNum, thefile.fName );
  407.                 err = FSpGetFInfo(&spec, &ioFlFndrInfo);
  408.  
  409.                 if (err == noErr) {
  410.                     Boolean changed = false;
  411.                     
  412.                     if (changeCreator && ioFlFndrInfo.fdCreator != creator)    {
  413.                         ioFlFndrInfo.fdCreator = creator;
  414.                         changed = true;
  415.                         }
  416.                     if (changeType && ioFlFndrInfo.fdType != type) {
  417.                         ioFlFndrInfo.fdType = type;
  418.                         changed = true;
  419.                         }
  420.                     
  421.                     if (changed) {        /* only write change if they happen */
  422.                         err = FSpSetFInfo(&spec,&ioFlFndrInfo);
  423.  
  424.                         if (err == noErr)
  425.                             err = TickleParent(&spec);    /* Force Finder to update folder info... */
  426.                         }
  427.                     }    /* End if no err */
  428.                 
  429.                 if (err != noErr)    ReportError(err);    /* End if Err */
  430.                 else
  431.                 if (type == 'TEXT' && EOLmode != IGNORE)    {
  432.                     err = DoConvertEOF(&spec, EOLmode);
  433.                     
  434.                     err = FSpSetFInfo(&spec, &ioFlFndrInfo);
  435.  
  436.                     if (err != noErr)    ReportError(err);    /* End if Err */
  437.                     }
  438.                 }    /* End for */
  439.         }
  440.     } else {
  441.         ReportError(err);
  442.         }
  443. }    /* End of ProcessFiles() */
  444.  
  445. #ifdef SelectAFile 
  446. Boolean SelectFile(DialogPtr dPtr, short sysRef)
  447. {    StandardFileReply reply;
  448.     SFTypeList typeList;
  449.     OSErr err;
  450.     FInfo        ioFlFndrInfo;
  451.     long        type, creator;
  452.     short        EOLmode, changeType, changeCreator, i;
  453.     
  454.     StandardGetFile(nil, -1,    typeList, &reply);
  455.     if (reply.sfGood) {
  456.             
  457.         
  458.         changeType = changeCreator = true;
  459.         EOLmode = IGNORE;
  460.         
  461.         err = FSpGetFInfo(&reply.sfFile, &ioFlFndrInfo);
  462.     
  463.         creator = ioFlFndrInfo.fdCreator;
  464.         type = ioFlFndrInfo.fdType;
  465.         SetDialogItemType(creator, CREATOR, dPtr);
  466.         SetDialogItemType(type, TYPE, dPtr);
  467.         type = LookType(&reply.sfFile, ioFlFndrInfo.fdType);
  468.         
  469.         /* Prompts for the file type and creator, 
  470.         */
  471.         if (err == noErr)    
  472.         if (AskNewTypeCreator(dPtr, sysRef,
  473.                                 &type, &creator, &changeType, &changeCreator, 
  474.                                 &EOLmode, &reply.sfFile)) {
  475.             
  476.             Boolean changed = false;
  477.                 
  478.             err = FSpGetFInfo(&reply.sfFile, &ioFlFndrInfo);
  479.             if (err == noErr) {
  480.                 if (changeCreator && ioFlFndrInfo.fdCreator != creator)    {
  481.                     ioFlFndrInfo.fdCreator = creator;
  482.                     changed = true;
  483.                     }
  484.                 if (changeType && ioFlFndrInfo.fdType != type) {
  485.                     ioFlFndrInfo.fdType = type;
  486.                     changed = true;
  487.                     }
  488.                 
  489.                 if (changed) {        /* only write change if they happen */
  490.                     err = FSpSetFInfo(&reply.sfFile,&ioFlFndrInfo);
  491.     
  492.                     if (err == noErr)
  493.                         err = TickleParent(&reply.sfFile);    /* Force Finder to update folder info... */
  494.                     }
  495.                 }        
  496.             
  497.             if (err == noErr && type == 'TEXT' && EOLmode != IGNORE)    {
  498.                 err = DoConvertEOF(&reply.sfFile, EOLmode);
  499.                 err = FSpSetFInfo(&reply.sfFile, &ioFlFndrInfo);
  500.                 }
  501.             }    /* End if AskNewTypeCreator() */
  502.             
  503.         if (err != noErr)    ReportError(err);    /* End if Err */
  504.     }
  505.     return reply.sfGood;
  506. }    /* End of () */
  507. #endif
  508.  
  509. void    main()
  510. {    short    message, count;
  511.     Ptr    size;
  512.     DialogPtr    dPtr;
  513.     SysEnvRec    theWorld;                         /* Environment record */
  514.     OSErr err;
  515.     GrafPtr    SavedPort;
  516.     
  517.     size = GetApplLimit();
  518.     SetApplLimit(size - 1024L);        /* make room on stack so Quickdraw can do big pictures */
  519.     
  520.      MaxApplZone();
  521.     
  522.     InitMacintosh();
  523.     
  524.     CountAppFiles(&message, &count);
  525.     if (message == 1) {
  526.         SysBeep(0);        /* Print items... ignore */
  527.         ExitToShell();
  528.         }
  529.         
  530.     GetPort(&SavedPort);            
  531.         
  532.     err = SysEnvirons(1, &theWorld);             /* Check how old this system is */
  533.     dPtr = DisplayDialog();
  534.     if (dPtr) {
  535.         if (theWorld.systemVersion >= 0x0700)
  536.                     SetDialogTracksCursor(dPtr, true);
  537.                     
  538.         if (count > 0) {    
  539.             ProcessFiles(dPtr, count, theWorld.sysVRefNum);
  540.         } else {
  541.         #ifdef SelectAFile 
  542.             SelectFile(dPtr, theWorld.sysVRefNum);
  543.         #else
  544.             SysBeep(0);
  545.         #endif
  546.             }
  547.             
  548.         DisposDialog(dPtr);
  549.     } else {
  550.         ReportError(MemError());    /* End if Err */
  551.         SysBeep(0);                                /* No dialog ... out of memory */
  552.         }
  553.     
  554.     SetPort(SavedPort);
  555.     ExitToShell();
  556. }    /* End of main() */
  557.